package com.lws.rxutils.asynconce;

import android.util.Log;
import android.view.View;

import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidDisposable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModel;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.disposables.DisposableContainer;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.schedulers.Schedulers;

public class SingleRxAsyncOnce<T> {

    private final Single<T> single;

    SingleRxAsyncOnce(@NonNull Single<T> single) {
        this.single = single.subscribeOn(Schedulers.io());
    }

    @CheckResult
    @NonNull
    public Disposable start(@NonNull Consumer<? super T> onSuccess) {
        return single.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess, throwable -> {
                    Log.e("TAG", "start: ", throwable);
                });
    }

    @CheckResult
    @NonNull
    public Disposable start(@NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        return single.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess, onError);
    }


    public void start(@NonNull DisposableContainer container, @NonNull Consumer<? super T> onSuccess) {
        single.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess, Debug::logOnThrowable, container);
    }

    public void start(@NonNull DisposableContainer container, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        single.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess, onError, container);
    }


    public void start(@NonNull LifecycleOwner lifecycleOwner, @NonNull Consumer<? super T> onSuccess) {
        start(AndroidDisposable.from(lifecycleOwner), onSuccess);
    }


    public void start(@NonNull LifecycleOwner lifecycleOwner, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        start(AndroidDisposable.from(lifecycleOwner), onSuccess, onError);
    }


    public void start(@NonNull Lifecycle lifecycle, @NonNull Consumer<? super T> onSuccess) {
        start(AndroidDisposable.from(lifecycle), onSuccess);
    }


    public void start(@NonNull Lifecycle lifecycle, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        start(AndroidDisposable.from(lifecycle), onSuccess, onError);
    }


    public void start(@NonNull ViewModel viewModel, @NonNull Consumer<? super T> onSuccess) {
        start(AndroidDisposable.from(viewModel), onSuccess);
    }


    public void start(@NonNull ViewModel viewModel, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        start(AndroidDisposable.from(viewModel), onSuccess, onError);
    }


    public void start(@NonNull View view, @NonNull Consumer<? super T> onSuccess) {
        start(AndroidDisposable.from(view), onSuccess);
    }


    public void start(@NonNull View view, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        start(AndroidDisposable.from(view), onSuccess, onError);
    }


}
